home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 February / EnigmA AMIGA RUN 15 (1997)(G.R. Edizioni)(IT)[!][issue 1997-02][PLANET CD V].iso / enigma / earcd / emula / arosdv19.lha / AROS / dos / lddemon.c < prev    next >
C/C++ Source or Header  |  1996-10-24  |  8KB  |  307 lines

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id: lddemon.c,v 1.8 1996/10/24 15:50:31 aros Exp $
  4.     $Log: lddemon.c,v $
  5.     Revision 1.8  1996/10/24 15:50:31  aros
  6.     Use the official AROS macros over the __AROS versions.
  7.  
  8.     Revision 1.7  1996/10/23 14:13:43  aros
  9.     Use AROS_ALIGN() to align pointers
  10.  
  11.     Revision 1.6  1996/10/21 20:44:51  aros
  12.     Changed d0 to D0
  13.  
  14.     Revision 1.5  1996/09/12 14:53:20  digulla
  15.     The loader code should use symbolic names
  16.  
  17.     Revision 1.4  1996/09/11 13:00:16  digulla
  18.     Use correct alignment (M. Fleischer)
  19.  
  20.     Revision 1.3  1996/08/13 13:52:48  digulla
  21.     Replaced <dos/dosextens.h> by "dos_intern.h" or added "dos_intern.h"
  22.     Replaced AROS_LA by AROS_LHA
  23.  
  24.     Revision 1.2  1996/08/01 17:40:53  digulla
  25.     Added standard header for all files
  26.  
  27.     Desc:
  28.     Lang: english
  29. */
  30. #include <exec/execbase.h>
  31. #include <exec/resident.h>
  32. #include <exec/memory.h>
  33. #include <exec/errors.h>
  34. #include <exec/libraries.h>
  35. #include <clib/exec_protos.h>
  36. #include <dos/dosextens.h>
  37. #include <clib/dos_protos.h>
  38. #include "dos_intern.h"
  39.  
  40. static BPTR LDLoad(STRPTR name, STRPTR basedir, struct DosLibrary *DOSBase)
  41. {
  42.     BPTR seglist;
  43.     struct Process *me=(struct Process *)FindTask(NULL);
  44.     struct DosList *dl1, *dl2;
  45.     struct Process *caller=DOSBase->dl_LDCaller;
  46.  
  47.     if(caller->pr_Task.tc_Node.ln_Type==NT_PROCESS)
  48.     {
  49.     /* Try the caller's current dir */
  50.     me->pr_CurrentDir=caller->pr_CurrentDir;
  51.     seglist=LoadSeg(name);
  52.     if(seglist)
  53.         return seglist;
  54.     }
  55.     /* Try the system's default directory. */
  56.     dl1=LockDosList(LDF_ALL|LDF_READ);
  57.     dl2=FindDosEntry(dl1,basedir,LDF_VOLUMES);
  58.     if(dl2==NULL)
  59.     dl2=FindDosEntry(dl1,basedir,LDF_DEVICES|LDF_ASSIGNS);
  60.     if(dl2!=NULL)
  61.     {
  62.     struct FileHandle fh;
  63.     fh.fh_Unit  =dl2->dol_Unit;
  64.     fh.fh_Device=dl2->dol_Device;
  65.     me->pr_CurrentDir=MKBADDR(&fh);
  66.     seglist=LoadSeg(name);
  67.     }
  68.     UnLockDosList(LDF_ALL|LDF_READ);
  69.     return seglist;
  70. }
  71.  
  72. static struct Library *LDInit(BPTR seglist, struct DosLibrary *DOSBase)
  73. {
  74.     BPTR seg=seglist;
  75.     while(seg)
  76.     {
  77.     STRPTR addr=(STRPTR)BADDR(seg)-AROS_ALIGN(sizeof(ULONG));
  78.     ULONG size=*(ULONG *)addr;
  79.     for(;size>=sizeof(struct Resident);size-=AROS_PTRALIGN,addr+=AROS_PTRALIGN)
  80.     {
  81.         struct Resident *res=(struct Resident *)addr;
  82.         if(res->rt_MatchWord==RTC_MATCHWORD&&res->rt_MatchTag==res)
  83.         {
  84.         struct Library *lib=InitResident(res,seglist);
  85.         if(lib==NULL)
  86.             UnLoadSeg(seglist);
  87.         return lib;
  88.         }
  89.     }
  90.     seg=*(BPTR *)BADDR(seg);
  91.     }
  92.     UnLoadSeg(seglist);
  93.     return NULL;
  94. }
  95.  
  96. void LDDemon(void)
  97. {
  98.     extern struct DosLibrary *DOSBase;
  99.     BPTR seglist;
  100.     for(;;)
  101.     {
  102.     Wait(SIGF_DOS);
  103.     seglist=LDLoad(DOSBase->dl_LDName,(STRPTR)DOSBase->dl_LDPtr,DOSBase);
  104.     DOSBase->dl_LDPtr=LDInit(seglist,DOSBase);
  105.     Signal(&DOSBase->dl_LDCaller->pr_Task,SIGF_DOS);
  106.     }
  107. }
  108.  
  109. AROS_LH2(struct Library *,OpenLibrary,
  110. AROS_LHA(STRPTR,libName,A1),AROS_LHA(ULONG,version,D0),
  111. struct ExecBase *,sysbase,0,Dos)
  112. {
  113.     AROS_LIBFUNC_INIT
  114.     extern struct DosLibrary *DOSBase;
  115.     struct Library *library;
  116.     Forbid();
  117.     library=(struct Library *)FindName(&SysBase->LibList,libName);
  118.     if(library==NULL)
  119.     {
  120.     ObtainSemaphore(&DOSBase->dl_LDSigSem);
  121.     DOSBase->dl_LDCaller=(struct Process *)FindTask(NULL);
  122.     DOSBase->dl_LDName  =libName;
  123.     DOSBase->dl_LDPtr   ="libs:";
  124.     Signal((struct Task *)DOSBase->dl_LDDemon,SIGF_DOS);
  125.     Wait(SIGF_DOS);
  126.     library=(struct Library *)DOSBase->dl_LDPtr;
  127.     ReleaseSemaphore(&DOSBase->dl_LDSigSem);
  128.     if(library!=NULL)
  129.         AddLibrary(library);
  130.     }
  131.     if(library!=NULL)
  132.     {
  133.     if(library->lib_Version>=version)
  134.         library=AROS_LVO_CALL1(struct Library *,
  135.         AROS_LCA(ULONG,version,D0),
  136.         struct Library *,library,1,
  137.         );
  138.     else
  139.         library=NULL;
  140.     }
  141.     Permit();
  142.     return library;
  143.     AROS_LIBFUNC_EXIT
  144. }
  145.  
  146. AROS_LH4(BYTE,OpenDevice,
  147.     AROS_LHA(STRPTR,devName,A0),
  148.     AROS_LHA(ULONG,unitNumber,D0),
  149.     AROS_LHA(struct IORequest *,iORequest,A1),
  150.     AROS_LHA(ULONG,flags,D1),
  151.     struct ExecBase *,sysbase,0,Dos)
  152. {
  153.     AROS_LIBFUNC_INIT
  154.     extern struct DosLibrary *DOSBase;
  155.     struct Device *device;
  156.     UBYTE ret=IOERR_OPENFAIL;
  157.     Forbid();
  158.     device=(struct Device *)FindName(&SysBase->DeviceList,devName);
  159.     if(device==NULL)
  160.     {
  161.     ObtainSemaphore(&DOSBase->dl_LDSigSem);
  162.     DOSBase->dl_LDCaller=(struct Process *)FindTask(NULL);
  163.     DOSBase->dl_LDName  =devName;
  164.     DOSBase->dl_LDPtr   ="devs:";
  165.     Signal((struct Task *)DOSBase->dl_LDDemon,SIGF_DOS);
  166.     Wait(SIGF_DOS);
  167.     device=(struct Device *)DOSBase->dl_LDPtr;
  168.     ReleaseSemaphore(&DOSBase->dl_LDSigSem);
  169.     if(device!=NULL)
  170.         AddDevice(device);
  171.     }
  172.     if(device!=NULL)
  173.     {
  174.     iORequest->io_Error=0;
  175.     iORequest->io_Device=device;
  176.     iORequest->io_Flags=flags;
  177.     iORequest->io_Message.mn_Node.ln_Type=NT_REPLYMSG;
  178.     AROS_LVO_CALL3(void,
  179.         AROS_LCA(struct IORequest *,iORequest,A1),
  180.         AROS_LCA(ULONG,unitNumber,D0),
  181.         AROS_LCA(ULONG,flags,D1),
  182.         struct Device *,device,1,
  183.     );
  184.     ret=iORequest->io_Error;
  185.     if(ret)
  186.         iORequest->io_Device=NULL;
  187.     }
  188.     Permit();
  189.     return ret;
  190.     AROS_LIBFUNC_EXIT
  191. }
  192.  
  193. AROS_LH1(void,CloseLibrary,
  194.     AROS_LHA(struct Library *,library,A1),
  195.     struct ExecBase *,sysbase,0,Dos)
  196. {
  197.     AROS_LIBFUNC_INIT
  198.     extern struct DosLibrary *DOSBase;
  199.     BPTR seglist;
  200.     if(library!=NULL)
  201.     {
  202.     Forbid();
  203.     seglist=AROS_LVO_CALL0(BPTR,
  204.         struct Library *,library,2,);
  205.     if(seglist)
  206.     {
  207.         DOSBase->dl_LDReturn=MEM_TRY_AGAIN;
  208.         UnLoadSeg(seglist);
  209.     }
  210.     Permit();
  211.     }
  212.     AROS_LIBFUNC_EXIT
  213. }
  214.  
  215. AROS_LH1(void,CloseDevice,
  216. AROS_LHA(struct IORequest *,iORequest,A1),
  217. struct ExecBase *,sysbase,0,Dos)
  218. {
  219.     AROS_LIBFUNC_INIT
  220.     extern struct DosLibrary *DOSBase;
  221.     BPTR seglist;
  222.     Forbid();
  223.     if(iORequest->io_Device!=NULL)
  224.     {
  225.     seglist=AROS_LVO_CALL1(BPTR,
  226.         AROS_LHA(struct IORequest *,iORequest,A1),
  227.         struct Device *,iORequest->io_Device,2,
  228.     );
  229.     iORequest->io_Device=(struct Device *)-1;
  230.     if(seglist)
  231.     {
  232.         DOSBase->dl_LDReturn=MEM_TRY_AGAIN;
  233.         UnLoadSeg(seglist);
  234.     }
  235.     }
  236.     Permit();
  237.     AROS_LIBFUNC_EXIT
  238. }
  239.  
  240. AROS_LH1(void,RemLibrary,
  241. AROS_LHA(struct Library *,library,A1),
  242. struct ExecBase *,sysbase,0,Dos)
  243. {
  244.     AROS_LIBFUNC_INIT
  245.     extern struct DosLibrary *DOSBase;
  246.     BPTR seglist;
  247.     Forbid();
  248.     seglist=AROS_LVO_CALL0(BPTR,
  249.     struct Library *,library,3,
  250.     );
  251.     if(seglist)
  252.     {
  253.     DOSBase->dl_LDReturn=MEM_TRY_AGAIN;
  254.     UnLoadSeg(seglist);
  255.     }
  256.     Permit();
  257.     AROS_LIBFUNC_EXIT
  258. }
  259.  
  260. LONG LDFlush(void)
  261. {
  262.     extern struct DosLibrary *DOSBase;
  263.     struct Library *library;
  264.  
  265.     DOSBase->dl_LDReturn=MEM_DID_NOTHING;
  266.  
  267.     /* Forbid() is already done, but I don't want to rely on it. */
  268.     Forbid();
  269.  
  270.     /* Follow the linked list of shared libraries. */
  271.     library=(struct Library *)SysBase->LibList.lh_Head;
  272.     while(library->lib_Node.ln_Succ!=NULL)
  273.     {
  274.     /* Flush libraries with a 0 open count */
  275.     if(!library->lib_OpenCnt)
  276.     {
  277.         RemLibrary(library);
  278.         /* Did it really go away? */
  279.         if(DOSBase->dl_LDReturn!=MEM_DID_NOTHING)
  280.         {
  281.         /* Yes. Return it. */
  282.         Permit();
  283.         return DOSBase->dl_LDReturn;
  284.         }
  285.     }
  286.     /* Go to next. */
  287.     library=(struct Library *)library->lib_Node.ln_Succ;
  288.     }
  289.     /* Do the same with the device list. */
  290.     library=(struct Library *)SysBase->DeviceList.lh_Head;
  291.     while(library->lib_Node.ln_Succ!=NULL)
  292.     {
  293.     if(!library->lib_OpenCnt)
  294.     {
  295.         RemLibrary(library);
  296.         if(DOSBase->dl_LDReturn!=MEM_DID_NOTHING)
  297.         {
  298.         Permit();
  299.         return DOSBase->dl_LDReturn;
  300.         }
  301.     }
  302.     library=(struct Library *)library->lib_Node.ln_Succ;
  303.     }
  304.     Permit();
  305.     return MEM_DID_NOTHING;
  306. }
  307.